/**
	This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package br.biofoco.p2p.rpc.rest;

import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MultivaluedMap;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import br.biofoco.p2p.services.AsyncToken;
import br.biofoco.p2p.services.Service;
import br.biofoco.p2p.services.ServiceTask;
import br.biofoco.p2p.services.ResultRepository;
import br.biofoco.p2p.services.ServiceCatalogue;
import br.biofoco.p2p.services.ServiceExecutor;
import br.biofoco.p2p.services.ServiceIDFactory;
import br.biofoco.p2p.peer.PeerNode;
import br.biofoco.p2p.utils.GuiceHelper;
import br.biofoco.p2p.utils.XMLUtils;

import com.google.common.collect.Maps;
import com.google.inject.Injector;

@Path("/")
public class PeerResource {

	private PeerNode node;
	private static final Injector injector = GuiceHelper.getInjector();
	private final ServiceCatalogue catalogue;
	private final ServiceExecutor executor;
	private final ResultRepository repository;
	
	public PeerResource() {
		catalogue = injector.getInstance(ServiceCatalogue.class);
		executor  = injector.getInstance(ServiceExecutor.class);
		repository = injector.getInstance(ResultRepository.class);
		
		executor.start();
	}
	
    @GET
	public String getPeer() {
    	node = PeerHandler.getPeer();    	
		return node.toString();
	}
    
    @GET
    @Path("services/{service-id}/{result-id}")
    @Produces("text/xml")
    public String getResult(@PathParam("service-id") String serviceID, @PathParam("result-id") String resultID) {
    	System.out.println(serviceID + " " + resultID);
    	return XMLUtils.serializeResult(repository.retrieve(resultID));
    }
    
    @GET
    @Path("services")
    @Produces("text/xml")
    public String getService(){
    	return XMLUtils.serializeList("services", "service", catalogue.listServices());
    }
    
//    @POST
//    @Path("upload")
//    @Consumes("multipart/form-data") 
//    @Produces("text/plain")
//    public String upload(InputStream stream){
//
//    	try {
//			BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
//			String line = null;
//			while ((line = reader.readLine()) != null) {
//				if (line.contains("file")){
//					reader.readLine();
//					
//				}
//				System.out.println(line);
//			}
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//
//    	return "OK";
//    }
    @POST
    @Path("upload")
    @Consumes("multipart/form-data")     
    @Produces("text/plain")
    public String upload(@Context HttpServletRequest request){
        FileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);
        try {
			List<?> itens = upload.parseRequest(request);
			for (Object item : itens){
				FileItem fi = (FileItem) item;
				if (!fi.isFormField()){
					System.out.println(fi.getName());
					fi.write(new File("/home/edward/tmp" + File.separator + fi.getName()));
				}
			}
		} catch (FileUploadException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return "OK";
    }    
   
    @POST
    @Path("services/{service-id}")
    @Consumes("application/x-www-form-urlencoded")
    @Produces("text/plain")
    public String submitServices(@PathParam("service-id") String serviceID, MultivaluedMap<String, String> formParams) {
    	
   	
    	System.out.println("Executing service with ID = " + serviceID);
    	
    	Long servID = Long.parseLong(serviceID.trim());
		Service<?> serv = catalogue.get(servID);


		Map<String, String> map = Maps.newHashMap();
		for (Entry<String,List<String>> entry: formParams.entrySet()){
			System.out.println(entry.getKey() + " " + entry.getValue());
			if (entry.getValue() != null && entry.getValue().size() >= 1)
				map.put(entry.getKey(), entry.getValue().get(0));
		}
		
		long id = ServiceIDFactory.newTaskID();
		ServiceTask task = new ServiceTask(id, serv, map);
		
		System.out.println("submitting task " + task.getID());		
		executor.submit(task);
		
		return XMLUtils.serializeToken(new AsyncToken(servID, task.getID()));
    }

}
